﻿namespace MSpecTests.WhoCanHelpMe.Web.Controllers
{
    using System.Web.Mvc;

    using global::WhoCanHelpMe.Domain;
    using global::WhoCanHelpMe.Domain.Contracts.Tasks;
    using global::WhoCanHelpMe.Web.Controllers.Profile.ActionFilters;

    using Machine.Specifications;

    using Rhino.Mocks;

    public abstract class specification_for_require_existing_profile_attribute
    {
        protected static ActionExecutingContext filter_context;

        protected static IProfileTasks profile_tasks;

        protected static IIdentityTasks identity_tasks;

        protected static string redirect_controller_name;

        protected static string redirect_action_name;

        protected static RequireExistingProfileAttribute sut;

        Establish context = () =>
            {
                ServiceLocatorHelper.InitialiseServiceLocator();

                identity_tasks = MockRepository.GenerateStub<IIdentityTasks>().AddToServiceLocator();
                profile_tasks = MockRepository.GenerateStub<IProfileTasks>().AddToServiceLocator();

                filter_context = new ActionExecutingContext();
            };

        protected static void CreateSut()
        {
            sut = new RequireExistingProfileAttribute(
                redirect_controller_name,
                redirect_action_name);
        }
    }

    public class when_the_require_existing_profile_attribute_is_used_and_the_user_has_a_profile : specification_for_require_existing_profile_attribute
    {
        static Identity the_identity;

        static Profile the_profile;

        static string user_name;

        Establish context = () =>
            {
                user_name = "username";

                the_identity = new Identity {
                                                UserName = user_name
                                            };

                the_profile = new Profile();

                redirect_controller_name = "controller";
                redirect_action_name = "action";

                identity_tasks.Stub(i => i.GetCurrentIdentity()).Return(the_identity);
                profile_tasks.Stub(p => p.GetProfileByUserName(user_name)).Return(the_profile);
                CreateSut();
            };

        Because b = () => sut.OnActionExecuting(filter_context);

        It should_ask_the_identity_tasks_for_the_current_identity = () => identity_tasks.AssertWasCalled(i => i.GetCurrentIdentity());

        It should_ask_the_profile_tasks_for_the_current_user_profile = () => profile_tasks.AssertWasCalled(p => p.GetProfileByUserName(user_name));

        It should_not_redirect = () => filter_context.Result.ShouldBeNull();
    }

    public class when_the_require_existing_profile_attribute_is_used_and_the_user_does_not_have_a_profile : specification_for_require_existing_profile_attribute
    {
        static Identity the_identity;

        static string user_name;

        Establish context = () =>
        {
            user_name = "username";

            the_identity = new Identity
            {
                UserName = user_name
            };

            redirect_controller_name = "controller";
            redirect_action_name = "action";

            identity_tasks.Stub(i => i.GetCurrentIdentity()).Return(the_identity);
            profile_tasks.Stub(p => p.GetProfileByUserName(user_name)).Return(null);
            CreateSut();
        };

        Because b = () => sut.OnActionExecuting(filter_context);

        It should_ask_the_identity_tasks_for_the_current_identity = () => identity_tasks.AssertWasCalled(i => i.GetCurrentIdentity());

        It should_ask_the_profile_tasks_for_the_current_user_profile = () => profile_tasks.AssertWasCalled(p => p.GetProfileByUserName(user_name));

        It should_redirect = () =>
            {
                filter_context.Result.IsARedirectToARouteAnd().RouteValues["controller"].ShouldEqual(redirect_controller_name);
                filter_context.Result.IsARedirectToARouteAnd().RouteValues["action"].ShouldEqual(redirect_action_name);
            };
    }
}
